قطاع الإنطلاق Boot Sector
(الجزء 1)
بسم الله الرحمن الرحيم
برمجة نظام التشغيل ككل مسار تطوير عنده بداية. لكن أجمل ما في هذه البداية أنها تتطابق مع بداية تشغيل الحاسب. إذ أن أول جزء يطور من نظام التشغيل هو قطاع الإنطلاق. الذي يعتبر أول برنامج ينفذ في نظام التشغيل بعد ال Bios.
ما هو قطاع الانطلاق ؟
قطاع الانطلاق هو ملف حجمه 512 byte. يكتب في أول قطاع من قرص مرن ، قرص صلب أو قسم (Partition) من قرص الصلب .و يمكن وضعه في خادم (Server) لكي ينطلق بواسطته جهاز مستخدم (Client).
يحتوي قطاع الانطلاق على ثلاثة أقسام :
قسم البيانات و المعلومات الخاصة بنظام الملفات المثبت على الدعامة أو قسم منها.
قسم البرنامج الذي سينفذ بعد ال Bios.
توقيع الصلاحية ( Bios Boot Signature ) : يدل على أن القطاع هو قطاع انطلاق و ليس قطاع عادي. و هو WORD مكتوب في نهاية القطاع يساوي 0xAA55، أي أن الByte رقم 510 = 0x55 و الByte رقم 511 = 0xAA ( الترقيم يبدأ من العدد 0 ).
مراحل انطلاق الحاسب:
1) بعد الضغط على زر تشغيل الحاسب يقوم هذا الأخير بتنفيذ برنامج ال Bios الموجود في ذاكرة ROM . يكون التنفيذ بعد نسخ ال Bios من الذاكرة ROM إلى الذاكرة المركزية RAM.
2) برنامج ال
Bios يقوم بإعداد بياناته الداخلية
و بالتحقق من سلامة المعدات و الأجهزة و تسمى هذه
العملية بـ POST
(Power On Self Test). ثم يبحث في
قائمة الدعامات التي تحتوي على قطاع الانطلاق . هذه القائمة قد تحتوي
مثلا على:
| ترتيب الدعامة | اسم الدعامة | شرح |
| 1 | floppy | أول قرص المرن (:a) |
| 2 | IDE0 | أول قرص صلب (:c) |
| 3 | CDROM |
أول قرص مضغوط |
3) يقرأ القطاع من أول دعامة متوفرة و يتأكد من وجود توقيع الصلاحية. إذا وجد التوقيع الصحيح يقوم بتحميل القطاع إلى العنوان 0000:7C00 و الموافق للعنوان المادي 0x7C00 .
4) يضع ال Bios رمز الدعامة التي تم تحميل القطاع منها في السجل DL. رموز بعض الدعامات هي:
| الدعامة | رمزها |
| القرص مرن رقم 1 | 0x00 |
| القرص الصلب رقم 1 | 0x80 |
| القرص الصلب رقم 2 | 0x81 |
5) في النهاية يقوم ال Bios
بقفز طويل (long jump) نحو العنوان 0000:7C00 بغرض تنفيذ البرنامج الموجود في قطاع
الانطلاق.
هذا الجدول يلخص محتوى السجلات قبل تنفيذ برنامج قطاع الانطلاق:
| السجلات | المحتوى |
| DL | رمز دعامة الانطلاق |
| CS | 0x0000 و هو عنوان قسم التعليمات الجديد. |
| IP | 0x7C00 و هو قيمة الانتقال داخل قسم التعليمات |
| جميع السجلات الأخرى | محتوى غير معرف |
6) هنا يأتي دور قطاع الانطلاق للتحكم في الحاسب.
كتابة أول قطاع انطلاق:
سنحاول الآن إن شاء الله كتابة قطاع انطلاق بسيط يكتب جملة "! Salam Alikom" ( "السلام عليكم" ) ثم يتوقف.
يجب أن نلاحظ أولا أن السجلات IP CS DL
هي الوحيدة التي تحتوي على قيم معرفة. لكننا نحتاج إلى وسط تنفيذي لبرنامج قطاع
الانطلاق.
يتكون الوسط التنفيذي من:
في ما يخص DS و ES يكفي اختيار القسم 07C0:0000 أي أن ES = DS =
0x07C0 . و هو نفسه العنوان 0000:7C00 .
أما الكومة فتختارها تبدأ في العنوان 9000:0000 أي
أن SS = 0x9000 و نختار SP = 0xFFFF
لنحصل على كومة بحجم 64kb.
هذا الرسم يلخص تقسيم الذاكرة المناسب للوسط التنفيذي لبرنامج قطاع الانطلاق:

بعد توفير الوسط التنفيذي نقوم برسم جملة "!
Salam Alikom".
لا نستطيع استعمال الوظيفة 9h للانقطاع
21h لأنها خاصة بنظام التشغيل MS-DOS
بل سنكتب إجراء صغير يرسم الجمل ويعتمد على الوظيفة 0Eh من الانقطاع
10h الخاص بال Bios. هذه الوظيفة
ترسم حرف واحد على الشاشة. الجدول التالي يصف هذه الوظيفة.
|
محتوى السجلات عند مناداة الانقطاع |
|
|
الوصف |
السجل |
|
رقم الوظيفة و هو 0Eh. |
AH = 0Eh |
| رمز الحرف في نظام الترميز ASCII. |
AL |
|
لون الحرف. |
BL |
|
النتائج |
|
|
لا شيء |
|
و في النهاية نوقف البرنامج بواسطة دوران غير منتهي. و هذا بالقفز إلى نفس البطاقة ( Label ).
البرنامج النهائي مكتوب بصيغة NASM و هو الملف boot.s . هذا هو محتواه:
|
[BITS 16] |
استعمال تعليمات بحجم 16 bit. |
| EntryPoint: | بداية برنامج قطاع الانطلاق. |
|
mov
ax,07c0h mov ds,ax mov es,ax |
تحضير الوسط التنفيذي لبرنامج قطاع الانطلاق. نضع في السجلين
DS و ES رقم القسم
0x07C0 عن طريق السجل AX. العنوان 07C0:0000 يمثل مكان وجود ملف قطاع الانطلاق في الذاكرة. |
|
mov ax,09000h mov ss,ax |
التصريح بكومة تبدأ قاعدتها من القسم 0x9000. |
|
mov
sp,0ffffh |
وضع العدد 0xFFFF في SP للحصول على كومة بحجم 64kb. |
|
mov si,Salam call ShowMsg |
نضع في السجل SI قيمة انتقال الجملة "!
Salam Alikom" داخل قسم البيانات. مناداة إجراء رسم الجمل. |
|
k_loop: jmp k_loop
|
حلقة مفرغة تهدف فقط إلى توقيف البرنامج. |
| ShowMsg: | بداية الإجراء ShowMsg (رسم جملة). |
|
push ax push bx |
حفظ السجلين AX و BX
في الكومة لأنهما سيستعملان في الإجراء. |
|
.loop_start: lodsb |
بداية حلقة تعليمات رسم جملة. و ضع Byte من العنوان [DS:SP] في السجل al. ( هو رمز الحرف المراد رسمه ). |
|
cmp al,0 je .loop_end |
التحقق من عدم نهاية الجملة بالعدد 0. في حالة al = 0 نقفز إلى نهاية حلقة التعليمات. |
| mov ah,0Eh | اختيار وظيفة رسم حرف ( الوظيفة رقم 0xE التابعة للانقطاع 0x10). |
| mov bx,07h | اختيار اللون الأبيض. |
| int 10h | مناداة الانقطاع 0x10 الخاص بال Bios. |
| jmp .loop_start | القفز إلى بداية حلقة التعليمات. |
| .loop_end: | نهاية حلقة التعليمات. |
|
pop bx pop ax |
استرجاع قيم AX و BX. |
|
ret |
نهاية إجراء رسم الجمل. و العودة إلى المنادي. |
|
Salam db "Salam Alikom !",13,10,0 |
التصريح بالجملة المراد كتابتها على الشاشة. |
| times
510-($-$$) db 0 |
التصريح بـ: 510-($-$$)
Byte ذات
القيمة 0 للحصول على 512
Byte في الملف المنتج و هو حجم قطاع انطلاق. $ : يرمز إلى مكان العبارة (Expression) الحالية داخل الملف الذي سينتج. $$ : يرمز إلى بداية القطعة (Section) الحالية من الملف الذي سينتج. |
| DW 0AA55h | التصريح بتوقيع الصلاحية (Bios Boot Signature). |
لصناعة قطاع الانطلاق نكتب الأمر التالي في سطر الأوامر (Command Line - Shell):
| nasm -f bin -o boot boot.s |
هذا الأمر يصنع الملف boot ذو الحجم 512
Byte.
التوجيه "o boot-" يأمر Nasm
بصناعة ملف اسمه "boot" . أما التوجيه "f
bin-" فتأمر Nasm بصناعة ملف خالي من كل معلومات
إضافية بل يحتوي فقط على تعليمات البرنامج مع بياناته.
كتابة قطاع الانطلاق على القرص المرن:
لتجربة قطاع الانطلاق الذي كتبناه يكفي كتابته في أول قطاع من
قرص المرن ثم إعادة تشغيل الجهاز لينطلق من هذا القرص.
ضع قرص مرن في قارئ القرص المرن. (كل الملفات الموجودة فيه ستفقد).
| dd if=boot of=/dev/fd0 |
| write |
الآن اعد تشغيل الجهاز. سينطلق الجهاز هذه المرة من القرص المرن
و يكتب الجملة "!
Salam Alikom".
يمكنك الآن القول بأنك قمت بخطوة صغيرة جدا و لكنها مهمة في طريق برمجة نظام تشغيل.
الحمد لله.
الملف"boot.s":
| [BITS 16] EntryPoint: mov ax,07c0h mov ds,ax mov es,ax mov ax,09000h mov ss,ax mov sp,0ffffh mov si,Salam call ShowMsg k_loop: jmp k_loop ShowMsg: push ax push bx .loop_start: lodsb cmp al,0 je .loop_end mov ah,0Eh mov bx,07h int 10h jmp .loop_start .loop_end: pop bx pop ax ret Salam db "Salam Alikom !",13,10,0 times 510-($-$$) db 0 DW 0AA55h |
الملف"write.s":
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ; file : write.s ; ; Synopsis: ; -------- ; This small program writes a file named "boot" on the first sector ; of a floppy, commonly known as the boot sector. ; ; To produce the com file "write.com" , type : ; nasm -f bin -o write.com write.s ; ; Author: Hamoud Mourad ; hmdz@alkhawarezmi.com ; ; Visit: www.alkhawarezmi.com ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; [bits 16] org 100h section .text start: ; open a file mov ax,0x3D40 mov dx,file_name int 21h jc error1 ; save file handle mov [handle],ax mov dx,msg_ok1 call show_msg read_file: mov ah,0x3F mov bx,[handle] mov cx,512 mov dx,buffer int 21h jc error2 cmp ax,512 jne error2 write_boot: mov ah,0 mov dl,0 int 13h mov ax,ds mov es,ax mov ax,0x0301 xor dx,dx mov cx,0x0001 mov bx,buffer int 13h jc error3 mov dx,msg_ok2 call show_msg close_file: ; close the file mov ah,0x3E mov bx,[handle] int 21h exit: mov ax,0x4c00 int 21h error1: mov dx,msg_error1 call show_msg call exit error2: mov dx,msg_error2 call show_msg call close_file error3: mov dx,msg_error3 call show_msg call close_file show_msg: push ax mov ah,0x09 int 21h pop ax ret section .data file_name db "boot",0 msg_ok1 db "file : boot --> opened",13,10,'$' msg_ok2 db "file : boot written on floppy successfully",13,10,'$' msg_error1 db "failed to open file : boot",13,10,'$' msg_error2 db "can't read 512 byte from file : boot",13,10,'$' msg_error3 db "can't write 512 byte on floppy",13,10,'$' section .bss buffer resb 512 handle resw 1 |
هذا الملف هو برنامج المصدر لـ: "write.com".
لصناعة الملف "write.com" نكتب في سطر الأوامر :
| nasm -f bin -o write.com write.s |
|
الكاتب : مراد حمود |
التاريخ : 13/12/2004 |